package com.gitee.luosl.cola.util;

import com.gitee.luosl.cola.lang.AbstractIterator;
import com.gitee.luosl.cola.lang.GroupedIterator;
import com.gitee.luosl.cola.lang.Tuple2;

import java.util.*;
import java.util.function.Predicate;

public class CollUtils {

    @SafeVarargs
    public static <T> List<T> newArrayList(T ...values){
        return new ArrayList<>(Arrays.asList(values));
    }

    @SafeVarargs
    public static <T> List<T> newLinkedList(T ...values){
        return new LinkedList<>(Arrays.asList(values));
    }

    @SafeVarargs
    public static <T> Set<T> newHashSet(T ...values){
        return new HashSet<>(Arrays.asList(values));
    }
    
    @SafeVarargs
    public static <K, V> Map<K, V> newHashMap(Tuple2<K, V> ...kvs) {
        HashMap<K, V> map = new HashMap<>();
        for(Tuple2<K, V> kv: kvs){
            map.put(kv._1, kv._2);
        }
        return map;
    }

    public static boolean isEmpty(Collection<?> coll){
        return null == coll || coll.size() == 0;
    }

    public static boolean isNotEmpty(Collection<?> coll){
        return !isEmpty(coll);
    }

    /**
     * 截取集合的部分
     *
     * @param <T> 集合元素类型
     * @param list 被截取的数组
     * @param start 开始位置（包含）
     * @param end 结束位置（不包含）
     * @return 截取后的数组，当开始位置超过最大时，返回空的List
     */
    public static <T> List<T> subList(List<T> list, int start, int end) {
        if (list == null || list.isEmpty()) {
            return Collections.emptyList();
        }

        final int size = list.size();
        if (start < 0) {
            start += size;
        }
        if (end < 0) {
            end += size;
        }
        if (start == size) {
            return new ArrayList<>(0);
        }
        if (start > end) {
            int tmp = start;
            start = end;
            end = tmp;
        }
        if (end > size) {
            if (start >= size) {
                return new ArrayList<>(0);
            }
            end = size;
        }

        return list.subList(start, end);
    }

    /**
     * 根据条件移除集合种的数据，并返回被移除的集合
     * @param data 带移除的集合
     * @param removeCondition 移除条件
     * @param <T> 数据集类型
     * @return 被移除的数据集 List<T>
     */
    public static <T> List<T> remove(Collection<T> data, Predicate<? super T> removeCondition){
        List<T> removeCollector = new ArrayList<>();
        Iterator<T> iterator = data.iterator();
        while (iterator.hasNext()) {
            T item = iterator.next();
            if(removeCondition.test(item)) {
                removeCollector.add(item);
                iterator.remove();
            }
        }
        return removeCollector;
    }

    public static <E> Collection<E> maxTopN(Iterator<E> itr, int topN, Comparator<E> comparator){
        PriorityQueue<E> heap = new PriorityQueue<>(topN, comparator);
        while (itr.hasNext()) {
            E item = itr.next();
            if(heap.size() < topN){
                heap.add(item);
            }else{
                if(comparator.compare(heap.peek(), item) < 0){
                    heap.poll();
                    heap.add(item);
                }
            }
        }
        return heap;
    }

    public static <E> Collection<E> minTopN(Iterator<E> itr, int topN, Comparator<E> comparator){
        return maxTopN(itr, topN, comparator.reversed());
    }

    public static <E> Collection<E> maxTopN(Iterator<E> itr, int topN){
        @SuppressWarnings("unchecked")
        Comparator<E> comp = (Comparator<E>) Comparator.naturalOrder();
        return maxTopN(itr, topN, comp);
    }

    public static <E> Collection<E> minTopN(Iterator<E> itr, int topN){
        @SuppressWarnings("unchecked")
        Comparator<E> comp = (Comparator<E>) Comparator.naturalOrder();
        return minTopN(itr, topN, comp);
    }

    public static <E> AbstractIterator<List<E>> sliding(Iterator<E> itr, int size, int step){
        return new GroupedIterator<>(itr, size, step);
    }

    public static <E> AbstractIterator<List<E>> sliding(Iterator<E> itr, int size){
        return sliding(itr, size, 1);
    }

}
